/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package edu.ucla.cs.CalorieCounter;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.Chronometer.OnChronometerTickListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;


/**
* This is the main Activity 
*/
public class HeartMonitor extends Activity {
    // Debugging
    private static final String TAG = "HeartMonitor";
    private static final boolean D = true;

    // Message types sent from the BluetoothChatService Handler
    public static final int MESSAGE_STATE_CHANGE = 1;
    public static final int MESSAGE_READ = 2;
    public static final int MESSAGE_WRITE = 3;
    public static final int MESSAGE_DEVICE_NAME = 4;
    public static final int MESSAGE_TOAST = 5;

    // Key names received from the BluetoothChatService Handler
    public static final String DEVICE_NAME = "device_name";
    public static final String TOAST = "toast";

    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;

    // Layout Views
    private TextView mTitle;
    // Name of the connected device
    private String mConnectedDeviceName = null;
    private TextView mTimeLabel;
    
    // Local Bluetooth adapter
    private BluetoothAdapter mBluetoothAdapter = null;
    // Member object for the chat services
    private HeartMonitorService mHeartService = null;
    
    private boolean pa = true; //pause
    
    // Calculated variables
	private double thresh = 0;
	static double avgRate;
	static double minAvg = 200;
	
	// Heart rate calculation variables
	private double interval = 0;
	private boolean above = false;
	
	// Global constants
	private static final double SAMPLE_RATE = 300;
	private static final double RATE_FLOOR = 30;
	private static final double RATE_CELLING = 150;
	
	// variables for calculating heart rate
	private int numRates = 0;
	private double heartRateTotal = 0;
	private final int MAXNUM = 300;
	
	private Chronometer mChronometer;
	private int start = 0;
	private int stop = 0;
	
	// Settings information
	private String mName = "";
	private float mWeight = 0;
	private int mAge = 0;
	private int mGender = 0; //0 = male, 1 = female
	
	private DatabaseHelper databasehelp;
	private CalorieModelHelper calorieModelHelper;
	
	private final String PREFS_NAME = "SETTINGS";
	
	private GraphicalView mChartView;
	
	// Timestamp format
	public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
	
	OnClickListener mStartListener = new OnClickListener()
	{
	    public void onClick(View v)	{
		    if (start == 0)	{
			    start = 1;
			    stop = 0;
			    mChronometer.start();
			    mChronometer.setBase(SystemClock.elapsedRealtime() - elapsedTimeBeforePause);
		    }
		    pa = false;
	    }
	};

	OnClickListener mStopListener = new OnClickListener()
	{
	    public void onClick(View v)	{
		    if (stop == 0)	{
			    stop = 1;
			    start = 0;
		        mChronometer.stop();
		        elapsedTimeBeforePause = SystemClock.elapsedRealtime() - mChronometer.getBase();
		        
		        TextView tv = (TextView) findViewById(R.id.textAverageHR);
				tv.setText(String.valueOf(((int) avgRate)));
				double cals = calcCalorie(mAge, mWeight, mGender, avgRate, elapsedTimeBeforePause/1000);
				tv = (TextView) findViewById(R.id.textCalBurned);
				DecimalFormat dec = new DecimalFormat("0.00");
				tv.setText(String.valueOf(dec.format(cals)));
		    }
		    pa = true;
	    }
	    
	    // Feed elapsedTimeBeforePause, mAge, mWeight, and mGender to the calorie function.
	    // Display results on textAverageHR and textCalBurned
	};

	OnClickListener mSaveRecordListener = new OnClickListener() {
		public void onClick(View v) {
			double cals = calcCalorie(mAge, mWeight, mGender, avgRate, elapsedTimeBeforePause/1000);
			insertCal(cals);
		}
	};
	
	OnClickListener mResetListener = new OnClickListener() {
	    public void onClick(View v)	{
		    stop = 0;
		    start = 0;
		    elapsedTimeBeforePause = 0;
	        mChronometer.setBase(SystemClock.elapsedRealtime());
	        mChronometer.stop();
	        
	        thresh = 0;
		    numRates = 0;
		    heartRateTotal = 0;
		    avgRate = 0;
	    }
	};
	
	private long elapsedSeconds;
	private long elapsedTimeBeforePause; //milliseconds
	
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.main);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
        
        mTitle = (TextView) findViewById(R.id.title_left_text);
        mTitle.setText(R.string.app_name);
        mTitle = (TextView) findViewById(R.id.title_right_text);
        
        moveMainPage();
        
        // Get local Bluetooth adapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
              
        Toast.makeText(this, "Blutooth initialized: " + mBluetoothAdapter.getName(), Toast.LENGTH_LONG).show();

        // If the adapter is null, then Bluetooth is not supported
        if (mBluetoothAdapter == null)
        {
            Toast.makeText(this, R.string.no_bluetooth, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        
        databasehelp = new DatabaseHelper(this);
        calorieModelHelper = new CalorieModelHelper(this);
        
        //load saved preferences
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        mName = settings.getString("name", "");
        
        //load rest of data from database
        if (mName.length() > 0)
        {
        	queryUser();
        }
    }

    @Override
    public void onStart()
    {
        super.onStart();
        if(D)
        	Log.d(TAG, "++ ON START ++");

        // If BT is not on, request that it be enabled.
        // setupHeartMonitor() will then be called during onActivityResult
        if (!mBluetoothAdapter.isEnabled())
        {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        // Otherwise, setup the chat session
        }
        else
        {
            if (mHeartService == null)
            	setupHeartMonitor();
        }
    }

    @Override
    public synchronized void onResume()
    {
        super.onResume();
        
        if(D)
        	Log.d(TAG, "+ ON RESUME +");

        // Performing this check in onResume() covers the case in which BT was
        // not enabled during onStart(), so we were paused to enable it...
        // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
        if (mHeartService != null)
        {
            // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mHeartService.getState() == HeartMonitorService.STATE_NONE)
            {
				// Start the Bluetooth chat services
				mHeartService.start();
            }
        }
    }

    private void setupHeartMonitor()
    {
    	if(D)
    		Log.d(TAG, "setupHeartMonitor()");

        // Initialize the HeartMonitorService to perform bluetooth connections
        mHeartService = new HeartMonitorService(this, mHeartHandler);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        // Stop the Bluetooth chat services
        if (mHeartService != null)
        	mHeartService.stop();
        if(D)
        	Log.d(TAG, "--- ON DESTROY ---");
    }

    public static String getHexString(byte[] b, int length) {
		String result = "";
		for (int i = 0; i < length; i++) {
			result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
		}
		return result;
	}
    
    // The Handler that gets information back from the HeartMonitorService
    private final Handler mHeartHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
	            case MESSAGE_STATE_CHANGE:
	            {
	                if(D)
	                	Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
	                
	                switch (msg.arg1)
	                {
		                case HeartMonitorService.STATE_CONNECTED:
		                {
		                    mTitle.setText(R.string.title_connected_to);
		                    mTitle.append(mConnectedDeviceName);
		                    break;
		                }
		                case HeartMonitorService.STATE_CONNECTING:
		                {
		                    mTitle.setText(R.string.title_connecting);
		                    break;
		                }
		                case HeartMonitorService.STATE_LISTEN:
		                case HeartMonitorService.STATE_NONE:
		                    mTitle.setText(R.string.title_not_connected);
		                    break;
	                }
	                break;
	            }
	            case MESSAGE_READ:
	            {
	            	if (!pa)
	            	{
	            		byte[] readBuf = (byte[]) msg.obj;
	            		
		                // construct a string from the valid bytes in the buffer
		                String readMessage = getHexString(readBuf, msg.arg1);
		                
		                //PacketHeader header = new PacketHeader(readMessage);
		                
		                String dataStr = readMessage.substring(12); //this is where the ECG starts
		               
		                Ecg myECG = new Ecg(dataStr);
		                ArrayList<Integer> ecgData = myECG.getData();
		                
		                // Update the threshold
						updateThresh(ecgData);

						// calculate the current Heart rate
						double curRate = calcHR(ecgData);
						
						//filter out improbable heart rates
						if (curRate > RATE_FLOOR && curRate < RATE_CELLING){	
							numRates++;
							heartRateTotal += curRate; 
							avgRate = heartRateTotal/numRates;
						}
						
						//moveWorkoutPage();
						//TextView tv = (TextView) findViewById(R.id.textCalBurned);
						//tv.setText(printTxt);
						
						// refresh rates once in a while
						if (numRates >= MAXNUM)
						{
							Toast.makeText(getApplicationContext(), "300 points", Toast.LENGTH_SHORT).show();
							numRates = 0;
							heartRateTotal = 0;
							if (avgRate < minAvg)
								minAvg = avgRate;
						}
	            	}
	                
					break;
	            }
	            case MESSAGE_DEVICE_NAME:
	            {
	                // save the connected device's name
	                mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
	                Toast.makeText(getApplicationContext(), "Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
	                break;
	            }
	            case MESSAGE_TOAST:
	            {
	                Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
	                break;
	            }
            }
        }
    };

    // Weight in kilograms
    // Gender: 0 = male, 1 = female
    // Time in seconds
    private double calcCalorie(int age, double weight, int gender, double averageHR, double time)
    {
    	double calPerMin;
    	
    	if (gender == 0)
    	{
    		calPerMin = (-55.0969 + 0.6309 * averageHR + 0.1988 * weight + 0.2017 * age) / 4.184;
    	}
    	else if (gender == 1)
    	{
    		calPerMin = (-20.4022 + 0.4472 * averageHR + 0.1263 * weight + 0.074 * age) / 4.184;
    	}
    	else
    	{
    		calPerMin = 0;
    	}
    	return calPerMin * (time / 60);
    }
    
    /* calculate the instantaneous heart rate */
	private double calcHR(ArrayList<Integer> heartData) {
		ArrayList<Double> intervals = new ArrayList<Double>();
		
		for(Integer data : heartData)
		{
			interval++;
			// if we exceeded the threshold
			if ((!above) && data > thresh)
			{
				above = true;
				// sometimes one beat may shift around the threshold, 
				// we filter out intervals that seem to be too small
				if (interval/SAMPLE_RATE > 60/(RATE_CELLING))
				{
					intervals.add(interval/SAMPLE_RATE);
					interval = 0;
				}
			}
			else if (above && data < thresh)
			{
				above = false;
			} 
		}
		
		int sum = 0;
		for (Double intv : intervals)
		{
			sum += 60/(intv);
		}
		
		return intervals.isEmpty()?-1:sum/intervals.size();	
	}

	
	private void updateThresh(ArrayList<Integer> ecgData)
	{
		double RMS, total, curMax, curMin, curThresh;
		// Initialize variables before calculation
		RMS = 0;
		total = 0;
		curMax = -9999;
		curMin = 9999;
		
		// Calculate the max, min, and total
		for (Integer data : ecgData)
		{
			if (data > curMax)
				curMax = data;
			if (data < curMin)
				curMin = data;
			total += data*data;
		}
		
		// Find the root mean square
		RMS = Math.sqrt(total/ecgData.size());
		
		// Calculate the threshold for this packet
		curThresh = RMS + (curMax - RMS) / 2;
		
		// If we haven't set the threshold before
		if (thresh == 0)
			thresh = curThresh;
		// Set the threshold in a weighted fashion
		else
			thresh = 0.5 * thresh + 0.5 * curThresh;		
	}
	
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if(D)
        	Log.d(TAG, "onActivityResult " + resultCode);
        
        switch (requestCode)
        {
	        case REQUEST_CONNECT_DEVICE:
	        {
	            // When DeviceListActivity returns with a device to connect
	            if (resultCode == Activity.RESULT_OK)
	            {
	                // Get the device MAC address
	                String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
	                // Get the BLuetoothDevice object
	                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
	                // Attempt to connect to the device
	                mHeartService.connect(device);
	            }
	            break;
	        }
	        case REQUEST_ENABLE_BT:
	        {
	            // When the request to enable Bluetooth returns
	            if (resultCode == Activity.RESULT_OK)
	            {
	                // Bluetooth is now enabled, so set up a chat session
	                setupHeartMonitor();
	            }
	            else
	            {
	                // User did not enable Bluetooth or an error occured
	                Log.d(TAG, "BT not enabled");
	                Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
	                finish();
	            }
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.option_menu, menu);
        return true;
    }
    
    /*
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) 
    {  
    	super.onCreateContextMenu(menu, v, menuInfo);  
    	menu.setHeaderTitle("Context Menu");  
    	menu.add(0, v.getId(), 0, "Select Device to Connect");    
    }
	*/
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
	        case R.id.scan:
	        {
	            // Launch the DeviceListActivity to see devices and do scan
	            Intent serverIntent = new Intent(this, DeviceListActivity.class);
	            startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
	            return true;
	        }
	        case R.id.pause:
	        {
				if(pa)
					 pa = false;
				else
					 pa = true;
				return true;
	        }
        }
        return false;
    }
    
    public void moveMainPage() {        
        setContentView(R.layout.main);
    	
        Button connectButton = (Button) findViewById(R.id.buttonConnect);
        connectButton.setOnClickListener(new OnClickListener () {
        	public void onClick(View v) {
        		moveWorkoutPage();
        	}
        });
        
        
    	Button settingsButton = (Button) findViewById(R.id.buttonSettings);
    	settingsButton.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			moveSettingsPage();
    		}
    	});
    	
    	Button startStatisticsButton = (Button) findViewById(R.id.buttonStatistics);
    	startStatisticsButton.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			moveStatisticsPage();
    		}
    	});
    	
    	//load rest of data from database
        if (mName.length() > 0)
        {
        	queryUser();
        }
    }
    
    public void moveSettingsPage() {
    	setContentView(R.layout.settings);
    	
    	//load data and set it to form
    	EditText nameInput = (EditText)findViewById(R.id.settingsNameInput);
		EditText ageInput = (EditText)findViewById(R.id.settingsAgeInput);
		EditText weightInput = (EditText)findViewById(R.id.settingsWeightInput);
		RadioButton maleButton = (RadioButton) findViewById(R.id.male);
    	RadioButton femaleButton = (RadioButton) findViewById(R.id.female);
    	maleButton.setOnClickListener(new OnClickListener () {
    		public void onClick(View v) {
    			mGender = 0;
    	    }
    	});
    	femaleButton.setOnClickListener(new OnClickListener () {
    		public void onClick(View v) {
    			mGender = 1;
    	    }
    	});
    	if (mName.length() > 0)
        {
    		nameInput.setText(mName);
    		ageInput.setText("" + mAge);
    		weightInput.setText("" + mWeight);
    		
    		if (mGender == 0)
    		{
    			maleButton.setChecked(true);
    			femaleButton.setChecked(false);
    		}
    		else
    		{
    			maleButton.setChecked(false);
    			femaleButton.setChecked(true);
    		}
        }
    	
    	Button saveButton = (Button) findViewById(R.id.buttonSaveSettings);
    	saveButton.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			
    			//save data
    			EditText nameInput = (EditText)findViewById(R.id.settingsNameInput);
    			mName = nameInput.getText().toString();
    			EditText ageInput = (EditText)findViewById(R.id.settingsAgeInput);
    			mAge =  Integer.valueOf(ageInput.getText().toString());
    			EditText weightInput = (EditText)findViewById(R.id.settingsWeightInput);
    			mWeight =  Float.valueOf(weightInput.getText().toString());
    			
    			if (mName.length() > 0)
    			{
    				//check if we have user
        			if (userExists())
        			{
        				updateUser();
        				uploadUserInfoToServer();
        			}
        			//else update current user
        			else
        			{
        				insertUser();
            			uploadUserInfoToServer();
        			}
        			
        			SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        	        SharedPreferences.Editor editor = settings.edit();
        	        editor.putString("name", mName);
        	        editor.commit();
    			}
    			
    	    	moveMainPage();
    		}
    	});
    	
    	Button cancelButton = (Button) findViewById(R.id.buttonBackS);
    	cancelButton.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			moveMainPage();
    			
    			//load variables from database (to ignore all previous changes)
    			//load saved preferences
    	        SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    	        mName = settings.getString("name", "");
    	        
    	        //load rest of data from database
    	        if (mName.length() > 0)
    	        {
    	        	queryUser();
    	        }
    		}
    	});
    	
    	
    }
    
    public void moveWorkoutPage() { 
    	setContentView(R.layout.workout);
    	
    	thresh = 0;
	    numRates = 0;
	    heartRateTotal = 0;
	    avgRate = 0;
    	
        mTimeLabel = (TextView) findViewById(R.id.time_label);
        mTimeLabel.setText("0:00");
        
        mChronometer = (Chronometer) findViewById(R.id.chrono);
        
        ((Button) findViewById(R.id.timer_start)).setOnClickListener(mStartListener);
        ((Button) findViewById(R.id.timer_stop)).setOnClickListener(mStopListener);
        ((Button) findViewById(R.id.timer_reset)).setOnClickListener(mResetListener);
        ((Button) findViewById(R.id.save_record)).setOnClickListener(mSaveRecordListener);
        
    	Button backButtonW = (Button) findViewById(R.id.buttonBackW);
    	backButtonW.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			moveMainPage();
    		}
    	});
        
        mChronometer.setOnChronometerTickListener(new OnChronometerTickListener(){
            @Override
            public void onChronometerTick(Chronometer arg0) {
            	elapsedSeconds = (SystemClock.elapsedRealtime() - arg0.getBase()) / 1000;
            	int minutes = (int)elapsedSeconds / 60;
            	int seconds = (int)elapsedSeconds % 60;
                String asText = "";
                if (seconds < 10)
                {
                	asText = minutes + ":0" + seconds;
                }
                else
                {
                	asText = minutes + ":" + seconds;
                } 
                mTimeLabel.setText(asText);
                
                TextView tv = (TextView) findViewById(R.id.textAverageHR);
				tv.setText(String.valueOf(((int) avgRate)));
				
				double cals = calcCalorie(mAge, mWeight, mGender, avgRate, elapsedSeconds);
				tv = (TextView) findViewById(R.id.textCalBurned);
				DecimalFormat dec = new DecimalFormat("0.00");
				tv.setText(String.valueOf(dec.format(cals)));
            }
        });
	
        Intent serverIntent = new Intent(this, DeviceListActivity.class);
        startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
    }
    
    public void moveStatisticsPage() {
    	setContentView(R.layout.statistics);
    	
    	Button backButtonT = (Button) findViewById(R.id.buttonBackT);
    	backButtonT.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			moveMainPage();
    		}
    	});
    	
    	//load rest of data from database
        if (mName.length() > 0)
        {
        	queryUser();
        	
        	TextView tv;
        	tv = (TextView) findViewById(R.id.settingsNameOutput);
        	tv.setText(mName);
        	tv = (TextView) findViewById(R.id.settingsAgeOutput);
        	tv.setText("" + mAge);
        	tv = (TextView) findViewById(R.id.settingsWeightOutput);
        	tv.setText("" + mWeight);
        	tv = (TextView) findViewById(R.id.settingsGenderOutput);
        	if (mGender == 0)
        	{
        		tv.setText("Male");
        	}
        	else
        	{
        		tv.setText("Female");
        	}
        }
        
        //get the calorie/date data
        GraphTuple data = queryCal();
        
	    int[] colors = new int[] { Color.RED };
	    PointStyle[] styles = new PointStyle[] { PointStyle.POINT };
	    
	    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
	    renderer.setAxisTitleTextSize(16);
	    renderer.setChartTitleTextSize(20);
	    renderer.setLabelsTextSize(15);
	    renderer.setLegendTextSize(15);
	    renderer.setPointSize(5f);
	    renderer.setMargins(new int[] { 20, 30, 15, 0 });
	    int length = colors.length;
	    for (int i = 0; i < length; i++)
	    {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(colors[i]);
			r.setPointStyle(styles[i]);
			renderer.addSeriesRenderer(r);
	    }
	    
	    renderer.setChartTitle("Exercise History");
	    renderer.setXTitle("Date");
	    renderer.setYTitle("Calories Burned");
	    
	    if (data.getSize() > 0)
	    {
	    	renderer.setXAxisMin(data.getDate(0).getTime());
	    	renderer.setXAxisMax(data.getDate(data.getSize() - 1).getTime());
	    }
	    
	    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
	    
	    double max = 0;
	    
	    TimeSeries series = new TimeSeries(mName);
	    for (int i = 0; i < data.getSize(); i++)
	    {
	    	double cal = data.getCalorie(i);
	    	if (cal > max)
	    		max = cal;
	    	
	    	series.add(data.getDate(i), cal);
	    }
	    dataset.addSeries(series);
	    
	    renderer.setYAxisMin(0);
	    renderer.setYAxisMax(max);
	    renderer.setAxesColor(Color.GRAY);
	    renderer.setLabelsColor(Color.LTGRAY);
	    renderer.setYLabels(10);
    	
	    LinearLayout layout = (LinearLayout) findViewById(R.id.mChartLayout);
        mChartView = ChartFactory.getTimeChartView(this, dataset, renderer, "MMM d, yyyy h:mm a");
        layout.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));   
    }
    
    //only run if mName is set
    private void insertUser(){
    	SQLiteDatabase db = databasehelp.getWritableDatabase();
    	
    	ContentValues cv = new ContentValues();
    	cv.put(DatabaseHelper.NAME, this.mName);
    	cv.put(DatabaseHelper.WEIGHT, this.mWeight);
    	cv.put(DatabaseHelper.AGE, this.mAge);
    	cv.put(DatabaseHelper.GENDER, this.mGender);
    	
    	db.insert(DatabaseHelper.TABLE_NAME, DatabaseHelper.NAME, cv);
    	
    	db.close();
    }
    
    //only run if mName is set
    private void updateUser() {
    	SQLiteDatabase db = databasehelp.getWritableDatabase();
    	
    	ContentValues cv = new ContentValues();
    	cv.put(DatabaseHelper.NAME, this.mName);
    	cv.put(DatabaseHelper.WEIGHT, this.mWeight);
    	cv.put(DatabaseHelper.AGE, this.mAge);
    	cv.put(DatabaseHelper.GENDER, this.mGender);
        
        db.update(DatabaseHelper.TABLE_NAME, cv, DatabaseHelper.NAME + "=?",  new String []{mName});
        db.close();
    }
    
    //only run if mName is set
    private void queryUser() {
    	SQLiteDatabase db = databasehelp.getReadableDatabase();
    	
    	Cursor c = db.query(DatabaseHelper.TABLE_NAME, null, DatabaseHelper.NAME + " = ?", new String []{mName}, null, null, null);
    	if (c != null)
    	{
            if (c.moveToFirst())
            {            	
            	mWeight = c.getFloat(2);
            	mAge = c.getInt(3);
            	mGender = c.getInt(4);;
            }

            // Closes the cursor.
            c.close();
        }
    	db.close();
    }
    
    private boolean userExists()
    {
    	boolean exist = false;
    	
    	SQLiteDatabase db = databasehelp.getReadableDatabase();
    	
    	Cursor c = db.query(DatabaseHelper.TABLE_NAME, null, DatabaseHelper.NAME + " = ?", new String []{mName}, null, null, null);
    	if (c != null)
    	{
    		if (c.moveToFirst())
    			exist = true;
            
            // Closes the cursor.
            c.close();
        }
    	db.close();
    	
    	return exist;
    }
    
    //only run if mName is set
    private void insertCal(double cals){
    	SQLiteDatabase db = calorieModelHelper.getWritableDatabase();
    	
    	ContentValues cv = new ContentValues();
    	cv.put(CalorieModelHelper.NAME, this.mName);
    	cv.put(CalorieModelHelper.CALORIE_BURNED, cals);
    	cv.put(CalorieModelHelper.TIME_STAMP, now());
    	
    	db.insert(CalorieModelHelper.TABLE_NAME, CalorieModelHelper.NAME, cv);
    	db.close();
    	
    	//update the database
    	uploadCalorieToSever(cals, now());
    }
    
    private static String now() {
    	Calendar cal = Calendar.getInstance();
    	SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
    	return sdf.format(cal.getTime());
    }
    
    private GraphTuple queryCal() {
    	SQLiteDatabase db = calorieModelHelper.getReadableDatabase();
    	
    	Cursor c = db.query(CalorieModelHelper.TABLE_NAME, null, CalorieModelHelper.NAME + " = ?", new String []{mName}, null, null, null);
    	
    	GraphTuple gt = new GraphTuple();
    	
    	SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT_NOW);
    	Date d = new Date();
    	String dateStr = "";
    	
    	if(c != null)
    	{
    		if (c.moveToFirst())
    		{
    			do
        		{
        			dateStr = c.getString(3);
        			try
        			{
        				d = formatter.parse(dateStr);
        				
        				gt.add(d, c.getFloat(2));
            			c.moveToNext();
    				}
        			catch (Exception e)
        			{
        				Log.e(TAG, "Parsing ISO8601 datetime failed", e);
    				}
        		}
        		while (c.moveToNext());
    		}
    		c.close();
    	}
    	
    	db.close();
    	
    	return gt;
    }
    
    private boolean uploadUserInfoToServer() {
    	String ipAddress = "http://calorie-counter.appspot.com/";
        RestClient client = new RestClient( ipAddress + "listenforrestclient");
        client.AddParam("u", mName);
        client.AddParam("w", String.valueOf(mWeight));
        if(mGender == 0)
        	client.AddParam("g", "male");
        else
        	client.AddParam("g", "female");
        client.AddParam("a", String.valueOf(mAge));
        client.AddParam("op", "create");
        
        try
        {
            client.Execute(RequestMethod.GET);
        }
        catch (Exception e)
        {
            Log.e(TAG, "Cannot excute request method", e);
        }
 
        String response = client.getResponse();
        Log.d(TAG, "Add here");
        if(response.equals("Success")) {
        	return true;
        } else
        	return false;
    }
    
    private boolean uploadCalorieToSever(double cals, String time) {
    	String ipAddress = "http://calorie-counter.appspot.com/";
        RestClient client = new RestClient( ipAddress + "workout");
        client.AddParam("u", mName);
        client.AddParam("cal", String.valueOf(cals));
        client.AddParam("t", time);
 
        try
        {
            client.Execute(RequestMethod.GET);
        }
        catch (Exception e)
        {
            Log.e(TAG, "Cannot excute request method", e);
        }
 
        String response = client.getResponse();
        if(response.equals("Success"))
        	return true;
        else
        	return false;
    }
}